import 'dart:async';

import 'package:get/get.dart';
import 'package:yt_devops/components/log_utils.dart';
import 'package:yt_devops/model/device_model.dart';
import 'package:yt_devops/pages/devices/device_list/device_list_model.dart';
import 'package:yt_devops/pages/devices/device_tab/model/device_item_model.dart';
import 'package:yt_devops/services/device/device_sevices.dart';
import 'package:yt_devops/utils/enums.dart';
import 'package:yt_devops/utils/formats.dart';
import 'package:yt_devops/utils/func_utils.dart';
import 'package:yt_devops/utils/socket/use_socket.dart';
import 'package:yt_devops/utils/socket/use_subscribe.dart';
import 'package:yt_devops/utils/useDeviceModel.dart';
import 'device_base_info_widget_model.dart';

class DeviceBaseInfoWidgetController extends GetxController {
  Map<int, DeviceListModel> flatDeviceIdMap = {}; //产品id和设备id对应关系
  List<Map<String, dynamic>> baseInfoList = [];
  DeviceModel? deviceModel;
  DeviceListModel? deviceTree;
  List<DeviceListModel> relateDeviceList = [];
  UseSubsribe deviceSubscribe = UseSubsribe();
  StreamSubscription? deviceStreamSubscription;
  UseSubsribe? connectStatusSubscribe;
  StreamSubscription? connectStatusStreamSubscription;
  UseSubsribe? extraDeviceSubscribe;
  StreamSubscription? extraDeviceStreamSubscription;
  DeviceServices deviceServices = Get.find();
  Map<String, dynamic> dataSource = {};
  DeviceBaseInfoWidgetModel? deviceBaseInfoWidgetModel;
  List<int> extraDeviceIdList = [];

  @override
  void onReady() {}

  @override
  void onClose() async {
    await deviceSubscribe.closeListen();
    await extraDeviceSubscribe?.closeListen();
    await connectStatusSubscribe?.closeListen();
    await deviceStreamSubscription?.cancel();
    await extraDeviceStreamSubscription?.cancel();
    await connectStatusStreamSubscription?.cancel();
    super.onClose();
  }

  ///初始化数据
  initData(DeviceModel model) async {
    subscribeCurDevice(deviceModel!.deviceId!);
    _initRelateDeviceList();
    if (deviceTree != null) {
      flatDeviceIdMap = getDeviceIdMap(deviceTree!, {});
    }

    _initBaseInfoList(model);
  }

  _initRelateDeviceList() {
    relateDeviceList = deviceTree?.childDeviceList?.fold<List<DeviceListModel>>(
            [],
            (pre, item) =>
                pre..addIf(item.deviceId != deviceModel?.deviceId, item)) ??
        [];
  }

  /// 获取整个设备树中 deviceId-device的map
  Map<int, DeviceListModel> getDeviceIdMap(
      DeviceListModel deviceTree, Map<int, DeviceListModel> pre) {
    pre.addAll({deviceTree.deviceId!: deviceTree});
    for (var child in (deviceTree.childDeviceList ?? [])) {
      pre = getDeviceIdMap(child, pre);
    }
    return pre;
  }

  /// 获取关联的所有productId
  List<int> relateProductIds(List<DetailItemModel> list) {
    var maps = flatDeviceIdMap.values.fold<Map<int, int>>(
        {}, (pre, item) => pre..addAll({item.productType!: item.productId!}));
    var productTypeIdList = FuncUtils.getPropFromTree<DetailItemModel, int>(
      list,
      getKey: (p) => p.productTypeId,
      getChildren: (p) => null,
    );
    return productTypeIdList.map((item) => maps[item]!).toList();
  }

  /// 获取关联的所有deviceId
  List<int> relateDeviceIds(List<int> productIdList) {
    var maps = flatDeviceIdMap.values.fold<Map<int, int>>(
        {}, (pre, item) => pre..addAll({item.productId!: item.deviceId!}));
    return productIdList.map((item) => maps[item]!).toList();
  }

  subscribeCurDevice(int deviceId) {
    deviceStreamSubscription =
        deviceSubscribe.start([deviceId], true).stream.listen((data) {
              updateData(data);
            });
  }

  subscribeExtraDevices(List<int> deviceIds) {
    extraDeviceSubscribe = UseSubsribe(isMultipleDevice: true);
    extraDeviceStreamSubscription =
        extraDeviceSubscribe!.start(deviceIds, true).stream.listen((data) {
      updateData(data);
    });
  }

  ///初始化基本信息列表数据
  _initBaseInfoList(DeviceModel model) async {
    deviceBaseInfoWidgetModel =
        DeviceBaseInfoWidgetModel(deviceModel!, flatDeviceIdMap);
    List<DetailItemModel> subDevices = [];
    if (model.productType == ProductType.ems.value) {
      subDevices = relateDeviceList
          .map<DetailItemModel>((item) => DetailItemModel(
                field: 'networkStatus',
                deviceId: item.deviceId,
                label: item.deviceName ?? item.name ?? '',
                format: Formates.onlineStatus,
              ))
          .toList();
      subDevices.insert(0, deviceBaseInfoWidgetModel!.allItemList['margin']!);
      _initSubscribeList(model, deviceTree);
    }

    var modelList = [
      ...deviceBaseInfoWidgetModel!.topList,
      ...deviceBaseInfoWidgetModel!.deviceInfoList,
      ...subDevices,
      ...deviceBaseInfoWidgetModel!.bottomList,
    ];
    preUpdateBaseInfo(modelList); //先展示
    List<int> productIdList = relateProductIds(modelList);
    extraDeviceIdList = relateDeviceIds(productIdList);
    subscribeExtraDevices(extraDeviceIdList);
    productIdList
      ..add(model.productId!)
      ..toSet()
      ..toList();

    var useModel = UseDeviceModel(productIds: productIdList);
    var deviceProperty = await useModel.getPropertyMap();
    baseInfoList.clear();
    for (var item in modelList) {
      var property = deviceProperty[item.field];

      if (item.show == null || item.show!(null, model) == true) {
        baseInfoList.add({
          'id': item.field,
          'deviceId': item.deviceId,
          'name': FuncUtils.isEmpty(item.label) ? property?.name : item.label,
          'value': '--',
          'format': item.format ??
              (value) {
                if (property?.dataType == null) {
                  return value;
                } else {
                  return FuncUtils.formatModelValue(value, property!.dataType,
                          isShowUnit: true)
                      .toString()
                      .trim();
                }
              },
        });
      }
    }
    updateData(model.toJson());
  }

  /// 初始化订阅列表
  _initSubscribeList(DeviceModel? device, DeviceListModel? deviceTree) {
    var subDevicesIdList = deviceTree?.childDeviceList?.fold<List<int>>(
            [],
            (pre, item) => pre
              ..addIf(item.deviceId != device?.deviceId, item.deviceId!)) ??
        [];

    if (device?.productType == ProductType.ems.value) {
      //如果是ems需要订阅从设备在线状态
      connectStatusSubscribe = UseSubsribe(isMultipleDevice: true);
      connectStatusStreamSubscription = connectStatusSubscribe
          ?.start(subDevicesIdList, true, type: MessageEventType.networkStatus)
          .stream
          .listen((event) {
        Log.d('从设备在线状态 $event');

        updateData(event);
      });
    }
  }

  updateSubscribeList(List<int> list) {}

  updateData(Map event) {
    dataSource = {...dataSource, ...event};

    for (var element in baseInfoList) {
      var id = element['id'];
      var realValue = FuncUtils.isEmpty(element['deviceId'])
          ? dataSource[id]
          : dataSource[element['deviceId'].toString()]?[id];

      if (element['format'] != null) {
        element['value'] =
            element['format']?.call(realValue)?.toString() ?? '--';
      } else {
        element['value'] = realValue?.toString() ?? '--';
      }
    }

    update();
  }

  preUpdateBaseInfo(List<DetailItemModel> list) {
    baseInfoList.clear();
    for (var item in list) {
      if (item.show == null || item.show!(null, deviceModel) == true) {
        baseInfoList.add({
          'id': item.field,
          'deviceId': item.deviceId,
          'name': item.label,
          'value': '--',
          'format': item.format
        });
      }
    }
    updateData(deviceModel?.toJson() ?? {});
  }
}
